package com.youlai.boot.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.system.mapper.*;
import com.youlai.boot.system.model.entity.*;
import com.youlai.boot.system.model.vo.RecordItem;
import com.youlai.boot.system.service.TransactionService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.system.service.ProcessRecordService;
import com.youlai.boot.system.model.form.ProcessRecordForm;
import com.youlai.boot.system.model.query.ProcessRecordQuery;
import com.youlai.boot.system.model.vo.ProcessRecordVO;
import com.youlai.boot.system.converter.ProcessRecordConverter;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.springframework.transaction.annotation.Transactional;

/**
 * 处理记录服务实现类
 *
 * @author youlaitech
 * @since 2025-02-28 16:53
 */
@Service
@RequiredArgsConstructor
public class ProcessRecordServiceImpl extends ServiceImpl<ProcessRecordMapper, ProcessRecord> implements ProcessRecordService {

    private final ProcessRecordMapper processRecordMapper;
    private final UserMapper userMapper;
    private final RecycleRequestMapper recycleRequestMapper;
    private final RequestWasteMapper requestWasteMapper;
    private final OrgMapper orgMapper;
    private final FileMapper fileMapper;
    private final TransactionService transactionService;

    /**
     * 获取处理记录分页列表
     *
     * @param queryParams 查询参数
     * @return {@link IPage<ProcessRecordVO>} 处理记录分页列表
     */
    @Override
    public IPage<ProcessRecordVO> getProcessRecordPage(ProcessRecordQuery queryParams) {
        // 构建自定义分页查询，直接在SQL中处理所有过滤条件
        Page<ProcessRecordVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
        IPage<ProcessRecordVO> resultPage = processRecordMapper.selectProcessRecordPage(page, queryParams);

        // 批量获取RequestWaste以减少查询次数
        List<ProcessRecordVO> records = resultPage.getRecords();
        if (CollUtil.isEmpty(records)) {
            return resultPage;
        }

        List<Long> requestIds = records.stream()
                .map(ProcessRecordVO::getRequestId)
                .distinct()
                .collect(Collectors.toList());

        if (CollUtil.isNotEmpty(requestIds)) {
            // 批量查询并按requestId分组
            Map<Long, List<RequestWaste>> wasteMap = requestWasteMapper.selectList(
                            new QueryWrapper<RequestWaste>().in("request_id", requestIds))
                    .stream()
                    .collect(Collectors.groupingBy(RequestWaste::getRequestId));

            // 填充wasteList到对应的VO中
            records.forEach(vo -> vo.setWasteList(wasteMap.getOrDefault(vo.getRequestId(), Collections.emptyList())));
        }

        return resultPage;
    }

    @Override
    public ProcessRecordVO getFormById(Long id) {

        ProcessRecordVO vo = new ProcessRecordVO();
        ProcessRecord processRecord = processRecordMapper.selectById(id);
        BeanUtil.copyProperties(processRecord, vo);

        RecycleRequest recycleRequest = recycleRequestMapper.selectById(processRecord.getRequestId());
        Long userId = recycleRequest.getUserId();
        Long orgId = recycleRequest.getOrgId();


        Map<Long, String> userMap = userMapper.selectList(null).stream().collect(Collectors.toMap(User::getId, User::getUsername));
        Map<Long, String> orgMap = orgMapper.selectList(null).stream().collect(Collectors.toMap(Org::getId, Org::getOrgName));

        // 发起人
        if (ObjectUtil.isNotNull(userId)) {
            vo.setUserId(userId);
            vo.setUsername(userMap.get(userId));
        }
        // 回收机构
        if (ObjectUtil.isNotNull(orgId)) {
            vo.setOrgId(orgId);
            vo.setOrgName(orgMap.get(orgId));
        }
        // 操作人
        if (ObjectUtil.isNotNull(vo.getOperationId())) {
            vo.setOperatorName(userMap.get(vo.getOperationId()));
        }

        //文件列表
        vo.setFileList(fileMapper.selectList(new QueryWrapper<File>().eq("record_id",vo.getId())).stream().map(File::getFileUrl).toList());
        return vo;
    }

    /**
     * 获取历史记录列表
     * @param requestId
     * @return
     */
    @Override
    public List<RecordItem> getHistoryRecord(Long requestId) {
        if (ObjectUtil.isNull(requestId)) {
            return List.of();

        }

        Map<Long, String> userMap = userMapper
                .selectList(null)
                .stream().collect(Collectors.toMap(User::getId, User::getUsername));

        List<RecordItem> historyLists = processRecordMapper
                .selectList(new LambdaQueryWrapper<ProcessRecord>()
                        .eq(ProcessRecord::getRequestId, requestId)
                        .ne(ProcessRecord::getProcessStatus, 0)
                        .ne(ProcessRecord::getProcessStatus, -1))
                .stream()
                .map(it -> RecordItem.builder()
                        .id(it.getId())
                        .requestId(it.getRequestId())
                        .operationId(it.getOperationId())
                        .operatorName(userMap.get(it.getOperationId()))
                        .createTime(it.getCreateTime())
                        .build()).toList();

        return historyLists;

    }

    /**
     * 新增记录
     * @param processRecordForm
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addRecord(ProcessRecordForm processRecordForm) {
        Long requestId = processRecordForm.getRequestId();
        List<ProcessRecord> records = processRecordMapper.selectList(new QueryWrapper<ProcessRecord>().eq("request_id", requestId));

        // 获取该请求下的最大记录值
        Integer processStatus = records.stream()
                .max(Comparator.comparing(ProcessRecord::getProcessStatus))
                .map(ProcessRecord::getProcessStatus)
                .orElseThrow(() -> new BusinessException("该请求下没有处理记录"));

        ProcessRecord entity = new ProcessRecord();
        BeanUtil.copyProperties(processRecordForm, entity);
        entity.setProcessStatus(processStatus + 1);
        boolean res = save(entity);
        // 存储文件
        if (CollUtil.isNotEmpty(processRecordForm.getFileList())) {
            processRecordForm.getFileList().forEach(it -> {
                File file = File.builder().
                        fileUrl(it)
                        .requestId(requestId)
                        .recordId(entity.getId())
                        .build();
                fileMapper.insert(file);
            });
        }


        return res;
    }

    /**
     * 更新记录
     * @param processRecordForm
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRecord(ProcessRecordForm processRecordForm) {
        ProcessRecord entity = new ProcessRecord();
        BeanUtil.copyProperties(processRecordForm, entity);
        // 先删后增
        if (CollUtil.isNotEmpty(processRecordForm.getFileList())) {
            List<Long> ids = fileMapper.selectList(new LambdaQueryWrapper<File>().eq(File::getRequestId, processRecordForm.getRequestId()).eq(File::getRecordId, entity.getId())).stream().map(File::getId).toList();
            if(CollUtil.isNotEmpty(ids)){
                fileMapper.deleteBatchIds(ids);
            }
            processRecordForm.getFileList().forEach(it -> {
                File file = File.builder()
                        .fileUrl(it)
                        .requestId(processRecordForm.getRequestId())
                        .recordId(entity.getId())
                        .build();
                fileMapper.insert(file);
            });
        }

        return updateById(entity);
    }

    /**
     * 删除记录
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeRecords(String ids) {
        if (StrUtil.isNotBlank(ids)) {
            List<Long> idList = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();
            fileMapper.delete(new LambdaQueryWrapper<File>().in(File::getRecordId, idList));
            processRecordMapper.deleteBatchIds(idList);
        }
        return true;
    }

}
